#pragma once

#include <memory>
#include "base.h"
#include "IRocksdb.h"

namespace rocksdb {
  class Comparator;
}

namespace helper {
namespace demo {

class ComparableRocksdb : public IRocksdb<Slice, Slice> {
public:
  using super = IRocksdb<Slice, Slice>;
  using key_type  = typename super::key_type;
  using value_type = typename super::value_type;
  using visitor = typename super::visitor;
  using iterator = typename super::iterator;
	using comparator_type = ::rocksdb::Comparator;

	static std::unique_ptr<ComparableRocksdb> Open(IRocksdb<key_type> & db, const comparator_type * comparator = nullptr);

public:
	ComparableRocksdb(super & db, const comparator_type &  comparator);
	~ComparableRocksdb() override;


  const std::string & name() const override;

  const OptionsArgs & optionsArgs() const override;
  OptionsArgs & optionsArgs()  override ;

  IDBInstance::DBImpl * instance() override ;
  Status put(const key_type & key, const value_type & value) override ;
  Status get(const key_type & key, std::string & value) const override;
  Status del(const key_type & key) override ;
  bool foreach(const visitor & v, const key_type & start, const key_type & end) const override ;
  iterator * range(const key_type& start, const key_type& end) const override ;


  Status put(const WriteOptions & write, const key_type & key, const value_type & value) override ;
  Status get(const ReadOptions & read, const key_type & key, std::string & value) const override ;
  Status del(const WriteOptions & write, const key_type & key) override ;
  bool foreach(const ReadOptions& read, const visitor & v, const key_type& start, const key_type & end) const override ;

  iterator * range(const ReadOptions & read, const key_type& start, const key_type& end) const override ;


protected:
	bool _open()override ;
	bool _close() override ;
private:
	const comparator_type & comparator_;
	IRocksdb<key_type> & db_;
};
}//namespace demo
}//namespace helper
